package org.ejc.api.payment;

import java.util.Date;

import javax.ejb.SessionBean;

import org.apache.log4j.Logger;
import org.ejc.exception.EJCPersistenceException;
import org.ejc.persist.model.Convention;
import org.ejc.persist.model.ConventionExecutive;
import org.ejc.persist.model.ConventionRegistrant;
import org.ejc.persist.model.Price;
import org.ejc.persist.model.Registrant;
import org.ejc.util.EJCUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;

/**
 * @author zac
 * 
 * @ejb.bean type="Stateless" name="PaymentAPI" description="PaymentAPI session
 *           bean" local-jndi-name="org.ejc/PaymentAPILocalHome"
 *           jndi-name="org.ejc/PaymentAPIHome" view-type="both"
 * 
 * @ejb.ejb-ref ejb-name="PaymentAPI" ref-name="ejb/PaymentAPI" view-type="both"
 * 
 * @ejb.transaction type="RequiresNew"
 * @ejb.util generate = "physical"
 */
public abstract class PaymentAPIBean implements SessionBean {

	
	private static Logger log = Logger.getLogger(PaymentAPIBean.class); 
	
	/**
	 * Create A Payment, which is esentially a row inserted into the transaction table with the 
	 * correct payment amount.
	 * @ejb.interface-method view-type="both"
	 * 
	 */
	public org.ejc.persist.model.Transaction createPayment(Integer conventionId, Integer registrantId,
			Integer conventionExecutiveId, Integer priceId,Double actualPrice) {
		// TODO: Create impl
		Session hsession = null;
		Transaction tx = null;
		try {
			hsession = EJCUtils.getHibernateSession();

			//get the price
			Price p = (Price) hsession.load(Price.class, priceId);

			//get the exec who is doing the insert
			ConventionExecutive exec = (ConventionExecutive) hsession.load(
					ConventionExecutive.class, conventionExecutiveId);

			//get the registrant
			Registrant registrant=(Registrant)hsession.load(Registrant.class,registrantId);
			
			//create the empty tx object
			org.ejc.persist.model.Transaction ejcTx = new org.ejc.persist.model.Transaction();

			//get the convention
			Convention conv = (Convention) hsession.load(Convention.class, conventionId);

			
			ejcTx.setConventionExecutive(exec);
			ejcTx.setRegistrant(registrant);
			ejcTx.setPrice(p);
			ejcTx.setTransactionAmount(actualPrice);
			ejcTx.setTransactionDate(new Date());
			ejcTx.setConvention(conv);
			tx = hsession.beginTransaction();
			tx.begin();
			Integer transactionId=(Integer)hsession.save(ejcTx);
			tx.commit();
			log.fatal("Transaction Inserted and its "+transactionId);
			ejcTx.setTransactionId(transactionId);
			return ejcTx;
		} catch (HibernateException hibe) {
			log.fatal("Persistence Exception",hibe);
			tx.rollback();
		} catch (Exception e) {
			log.fatal("General Exception",e);
			tx.rollback();
		} finally {
			hsession.close();
		}
		return null;
	}
	
	/**
	 * Validate whether a payment has already been made for this registrant.
	 * If it has then return false
	 * @ejb.interface-method view-type="both"
	 * 
	 */
	public boolean validatePayment(Integer registrantId)
	{
		Session hsession = null;
		org.ejc.persist.model.Transaction transaction = null;
		try {
			hsession = EJCUtils.getHibernateSession();
			log.debug("Searching for transaction with ID ["+registrantId+"]");
			transaction = (org.ejc.persist.model.Transaction) hsession.createCriteria(org.ejc.persist.model.Transaction.class)
				.add(Expression.eq("registrantId", registrantId));
			log.debug("Found Transaction for Id ["+registrantId+"]");
			if(transaction != null){
				return false;
			}
			
		} catch (EJCPersistenceException e) {
			log.fatal("Error getting Hibernate Session instance when selecting a Transaction by RegistrantId");
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * tester
	 */
	public void test() {
		Registrant registrant = new Registrant();
		registrant.setRegistrantId(4);

		Session hsession = null;
		Transaction tx = null;
		try {
			hsession = EJCUtils.getHibernateSession();

			Price p = (Price) hsession.load(Price.class, 1);
			ConventionExecutive exec = (ConventionExecutive) hsession.load(
					ConventionExecutive.class, 1);

			org.ejc.persist.model.Transaction ejcTx = new org.ejc.persist.model.Transaction();

			ejcTx.setConventionExecutive(exec);
			ejcTx.setRegistrant(registrant);
			ejcTx.setPrice(p);
			ejcTx.setTransactionAmount(p.getPriceAmount());
			ejcTx.setTransactionDate(new Date());
			Convention conv = (Convention) hsession.load(Convention.class, 1);

			ejcTx.setConvention(conv);
			tx = hsession.beginTransaction();
			tx.begin();
			hsession.saveOrUpdate(ejcTx);
			tx.commit();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
